package com.xiaohe66.web.infrastructure.mybatis.sys.sec.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaohe66.common.ex.HeException;
import com.xiaohe66.common.util.Assert;
import com.xiaohe66.common.util.IdWorker;
import com.xiaohe66.web.domain.account.value.AccountId;
import com.xiaohe66.web.domain.sys.sec.agg.SysConfig;
import com.xiaohe66.web.domain.sys.sec.repository.SysConfigRepository;
import com.xiaohe66.web.domain.sys.sec.value.SysConfigId;
import com.xiaohe66.web.domain.sys.sec.value.SysConfigKey;
import com.xiaohe66.web.domain.sys.sec.value.SysJwtSecret;
import com.xiaohe66.web.domain.sys.sec.value.SysSecretKey;
import com.xiaohe66.web.infrastructure.mybatis.sys.sec.convert.SysConfigDoConverter;
import com.xiaohe66.web.infrastructure.mybatis.sys.sec.mapper.SysConfigMapper;
import com.xiaohe66.web.infrastructure.mybatis.sys.sec.model.SysConfigDo;
import com.xiaohe66.web.integration.AbstractMybatisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author xiaohe
 * @since 2023-12-27 17:41
 */
@Repository
@Slf4j
@RequiredArgsConstructor
public class SysConfigRepositoryImpl
        extends AbstractMybatisService<SysConfigDoConverter, SysConfigMapper, SysConfigDo, SysConfig, SysConfigId>
        implements SysConfigRepository {

    @Override
    public SysConfig getByKey(SysConfigKey key) {

        SysConfigDo dbConfig = getByKey(key.getValue());

        SysConfig agg = dataConverter.toAgg(dbConfig);

        saveSnapshot(agg);

        return agg;
    }

    public SysConfigDo getByKey(String key) {

        Assert.requireNotNull(key);

        LambdaQueryWrapper<SysConfigDo> queryWrapper = new LambdaQueryWrapper<SysConfigDo>()
                .eq(SysConfigDo::getConfigKey, key);

        return getOne(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveSysSecretKey(SysSecretKey secretKey) {

        SysConfigDo privateKeyConfig = new SysConfigDo();
        privateKeyConfig.setId(IdWorker.genId());
        privateKeyConfig.setCreateId(AccountId.SYSTEM_ID.getValue());
        privateKeyConfig.setConfigKey(SysConfigKey.SYS_PRIVATE_KEY_KEY.getValue());
        privateKeyConfig.setConfigValue(secretKey.getPrivateKey());

        SysConfigDo publicKeyConfig = new SysConfigDo();
        publicKeyConfig.setId(IdWorker.genId());
        publicKeyConfig.setCreateId(AccountId.SYSTEM_ID.getValue());
        publicKeyConfig.setConfigKey(SysConfigKey.SYS_PUBLIC_KEY_KEY.getValue());
        publicKeyConfig.setConfigValue(secretKey.getPublicKey());

        List<SysConfigDo> list = List.of(privateKeyConfig, publicKeyConfig);

        saveBatch(list);
    }

    @Override
    public SysSecretKey getSysSecretKey() {

        SysConfigDo privateConfig = getByKey(SysConfigKey.SYS_PRIVATE_KEY_KEY.getValue());
        SysConfigDo publicConfig = getByKey(SysConfigKey.SYS_PUBLIC_KEY_KEY.getValue());

        if (privateConfig == null && publicConfig == null) {
            return null;

        } else if (privateConfig == null || publicConfig == null) {
            throw new HeException("system exception, privateKey or publicKey is null");
        }

        return new SysSecretKey(privateConfig.getConfigValue(), publicConfig.getConfigValue());
    }

    @Override
    public void saveJwtSecret(SysJwtSecret jwtSecret) {

        SysConfigDo jwtSecretConfig = new SysConfigDo();
        jwtSecretConfig.setId(IdWorker.genId());
        jwtSecretConfig.setCreateId(AccountId.SYSTEM_ID.getValue());
        jwtSecretConfig.setConfigKey(SysConfigKey.SYS_JWT_SECRET_KEY.getValue());
        jwtSecretConfig.setConfigValue(jwtSecret.getValue());

        save(jwtSecretConfig);
    }

    @Override
    public SysJwtSecret getSysJwtSecret() {

        SysConfigDo jwtSecretConfig = getByKey(SysConfigKey.SYS_JWT_SECRET_KEY.getValue());

        return jwtSecretConfig == null ? null : new SysJwtSecret(jwtSecretConfig.getConfigValue());
    }
}
